'''
Created on 30-09-2012

@author: LONG HOANG GIANG
'''
from Crypto import Random
from Crypto.Cipher import AES
import base64

BLOCK_SIZE = 32
pkcs5pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)
pkcs5unpad = lambda s: s[0:-ord(s[-1])]

CIPHER_KEY = 'bG9uZ2hvYW5nZ2lhbmc='
IV_KEY = 'z4mP372E3t17686W'

class AESCipher():
    
    '''encrypt CBC mode with padding PKCS5Padding (AES/CBC/PKCS5Padding)'''
    
    def __init__(self, key=CIPHER_KEY):
        self.key = pkcs5pad(base64.decodestring(key))
        self.iv = Random.new().read(AES.block_size)
    
    def encrypt(self, plaintext, **kw):
        iv = IV_KEY
        cipher = AES.new(self.key, AES.MODE_CBC, iv)
        if isinstance(plaintext, unicode): plaintext = plaintext.encode('utf-8')
        result = base64.urlsafe_b64encode(iv + cipher.encrypt(pkcs5pad(plaintext))) if kw.get('url_safe', False) else base64.b64encode(iv + cipher.encrypt(pkcs5pad(plaintext))) 
        return result
    
    def decrypt(self, ciphertext, **kw):
        ciphertext = base64.b64decode(ciphertext) if not kw.get('url_safe', False) else base64.urlsafe_b64decode(ciphertext)
        cipher = AES.new(self.key, AES.MODE_CBC, ciphertext[0:16])
        return pkcs5unpad(cipher.decrypt(ciphertext[16:]))
    
    def toHex(self, data):
        output = ""
        for char in data:
            output += str(hex(ord(char)))[2:]
        return output
    
